// gulp 入口文件
const { src, dest, series, parallel } = require('gulp')

const del = require('del')
const browserSync = require('browser-sync')
const loadPlugins = require('gulp-load-plugins')
const { watch } = require('browser-sync')

const plugins = loadPlugins()
const bs = browserSync.create()
const cwd = process.cwd()  // 工作目录

// 定义项目相关的默认配置项
let config = {
    build: {
        configPath: 'pages.config.js',
        src: 'src',
        dist: 'dist',
        temp: 'temp',
        public: 'public',
        paths: {
            styles: 'assets/styles/*.scss',
            scripts: 'assets/scripts/*.js',
            typescripts: 'assets/ts/*.ts',
            pages: '*.html',
            image: 'assets/images/**',
            fonts: 'asssets/fonts/**'
        }
    }
}

// 加载用户配置文件
try {
    const loadConfig = require(`${cwd}/pages.config.js`)
    config = Object.assign({}, config, loadConfig)
} catch (error) {
    
}

// 清理临时文件和打包生成的文件
const clean = () => {
    return del([config.build.temp, config.build.dist])  // temp 是临时目录
}

// html 模板转换、压缩
const html = () => {
    return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
        // .pipe(swig())
        .pipe(plugins.swig({ data: config.data, cache: false }))
        .pipe(dest(config.build.temp))
        .pipe(bs.reload({ stream: true }))  // 文件发生变化自动刷新浏览器
}

// css 转换、合并、压缩
const css = () => {
    return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src, sourcemaps: true })
        .pipe(plugins.sass()) // 会忽略_开头的文件 认为是主文件的依赖文件
        .pipe(dest(config.build.temp))
        .pipe(bs.reload({ stream: true }))
}

// js 转换、合并、压缩
const javascript = () => {
    return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src, sourcemaps: true })
        // .pipe(babel({ presets: ['@babel/preset-env'] }))
        .pipe(plugins.babel({ presets: [require('@babel/preset-env')] })) // require 会从当前文件向上查找
        .pipe(dest(config.build.temp))
}

// ts 转换、合并、压缩
const typescript = () => {
    return src(config.build.paths.typescripts, { base: config.build.src, cwd: config.build.src, sourcemaps: true })
        .pipe(dest(config.build.temp))
}

// image 压缩
const imgmini = () => {
    return src(config.build.paths.image, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.imagemin())
        .pipe(dest(config.build.dist))
        .pipe(bs.reload({ stream: true }))
}

// image 生成雪碧图
const spritesmith = () => {
    return src('src/**/**')
        .pipe(dest(config.build.dist))
}

// font 压缩
const font = () => {
    return src(config.build.paths.image, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.imagemin())
        .pipe(dest(config.build.dist))
        .pipe(bs.reload({ stream: true }))
}

// 其他文件
const extra = () => {
    return src('**', { base: config.build.src, cwd: config.build.src })
        .pipe(dest(config.build.public))
}


/**
 * 开发体验上的增强
 *  1. 热更新开发服务器 borwser-sync
 *  2. 自动编译  gulp.watch
*/

const serve = () => {
    watch(config.build.paths.pages, { cwd: config.build.src }, html)
    watch(config.build.paths.styles, { cwd: config.build.src }, css)
    watch(config.build.paths.scripts, { cwd: config.build.src }, javascript)

    // 监听 img fonts 
    watch([
        config.build.paths.image,
        config.build.paths.fonts
    ], { cwd: config.build.src }, bs.reload)

    // 监听 extra
    watch('**', { cwd: config.build.public })

    bs.init({
        notify: false,  // 是否显示更新通知
        open: true,     // 是否自动打开浏览器 默认 true
        port: 8090,
        server: {
            baseDir: [config.build.temp, config.build.src, config.build.public], // 从前往后依次查找
            routes: { // 优先于baseDir 先从 routes查找
                '/node_modules': 'node_modules'
            }
        }
    })
}


/**
 * useref 自动处理html文件当中的构建注释
 * <!-- build:js assets/scripts/vendor.js --> <!-- endbuild -->
*/

const useref = () => {
    return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
        .pipe(plugins.useref({ searchPath: [ config.build.temp, '.' ] }))  // dist 目录下  项目根目录下 . 使用最多的情况放在前面
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({  // 压缩html 
            collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true
        })))
        .on('error', function(err) {
            plugins.util.log(plugins.util.colors.red('[error]'), err.toString())
        })
        .pipe(dest(config.build.dist)) // 将读取流、写入流分离开 避免产生冲突
}


// 处理文件
const compile = parallel(html, css, javascript, typescript)

// 上线之前 build
const build = series(clean, parallel(series(compile, useref), extra, imgmini, font))

const start = series(compile, serve)

module.exports = {
    build,
    compile,
    clean,
    serve,
    start
}

// 首先 安装gulp
// 新建gulp入口文件 gulpfile.js
// 编写默认的配置项数据
// 定义所需要的任务
